﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HurSimLib
{
   /// <summary>
   /// A wrapper class for a pseudo-random number generator used to
   /// set the creation times of objects.
   /// </summary>
   public class HurObjectGenerator
   {
      //Creation time limits for the objects to be generated
      private DateTime m_initialtime;
      private DateTime m_endtime;
      /// <summary>
      /// The generator based on a random number distribution
      /// which will be used to set creation times of objects
      /// </summary>
      private Troschuetz.Random.Distribution m_distribution;
      /// <summary>
      /// The time unit to be used in genrating object creation times
      /// </summary>
      public TimeUnit GeneratorTimeUnit;
      /// <summary>
      /// The process which wil receive the objects after this one.
      /// </summary>
      private HurProcess m_nextprocess;

      /// <summary>
      /// The empty constructor starts with blank times
      /// </summary>
      public HurObjectGenerator()
      {
         m_initialtime = m_endtime = new DateTime(
            DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0);
      }

      /// <summary>
      /// This constructor receives the underlying distribution as an argument
      /// </summary>
      /// <param name="gendist"></param>
      public HurObjectGenerator(Troschuetz.Random.Distribution gendist):this()
      {
         m_distribution = gendist;
      }
      /// <summary>
      /// This property gets/sets the time of start for the object generation
      /// </summary>
      public DateTime GenerationStart
      {
         get { return m_initialtime; }
         set { m_initialtime = value; }
      }
      /// <summary>
      /// This property gets/sets the end time of the object generation
      /// </summary>
      public DateTime GenerationEnd
      {
         get { return m_endtime; }
         set { m_endtime = value; }
      }

      public HurProcess NextProcess
      {
         get { return m_nextprocess; }
         set { m_nextprocess = value; }
      }

      /// <summary>
      /// This property gets'sets the underlying random generation distribution
      /// </summary>
      public Troschuetz.Random.Distribution GeneratorDistribution
      {
         get { return m_distribution; }
         set { m_distribution = value; }
      }

      /// <summary>
      /// This function generates objects untila specified time and places
      /// them in the next process' queue.
      /// </summary>
      /// <param name="nextprocess">The process which will receive the created objects</param>
      public HurObject Generate()
      {
         double timeperiod;
         DateTime currenttime;
         HurObject newobject;
         currenttime = m_initialtime;

         while(currenttime < m_endtime)
         {
            timeperiod = m_distribution.NextDouble();
            currenttime = Common.NextTime(currenttime, timeperiod, GeneratorTimeUnit);
            newobject = new HurObject(currenttime);
             
            // Send the object to the next process.
            // The process will place the object in its procesing queue (if any).
            m_nextprocess.EnterObject(newobject);
            return newobject;
         }
         return null;
      }
   }
}
